﻿#include "OiPCH.hpp"
#include "PLScannerCore/Tools/OiPlyTool.hpp"
#include <QtCharts/QChart>
#include <QtCharts/QValueAxis>

namespace Oi
{
    using namespace PLScannerCore;

    namespace PLScannerDll
    {
        class ValueSplineView : public DynamicSplineView
        {
        public:
            ValueSplineView(const QStringList list, QWidget *parent = Q_NULLPTR);
            ~ValueSplineView();

        public:
            QMap<QString, QList<QPointF>> loadData(const QDateTime from, const QDateTime end);
            void addData(const qreal dt, QMap<QString, qreal> data);

        public:
            QStringList splineList;

//         public:
//             QList<QPointF> _values;

        };

        ValueSplineView::ValueSplineView(const QStringList list, QWidget *parent /*= Q_NULLPTR*/)
            : DynamicSplineView(list, parent)
        {
            splineList = list;
            //chart()->setFlashFitMode(DynamicSplineChart::FitToData);
            auto axis = qobject_cast<QtCharts::QValueAxis*>(chart()->axisY());
            axis->setLabelFormat("%.2f");
            axis->setTickCount(6);

            chart()->setXRange(10 * 60);
           // axis->setRange(0.0, 1.0);
        }

        ValueSplineView::~ValueSplineView()
        {

        }

        QMap<QString, QList<QPointF>> ValueSplineView::loadData(const QDateTime from, const QDateTime end)
        {
            QMap<QString, QList<QPointF>> datas;

            for (auto & key : splineList)
            {
                datas[key] = QList<QPointF>();
            }

            return datas;

        }

        void ValueSplineView::addData(const qreal dt, QMap<QString, qreal> data)
        {
            chart()->addValues(dt, data);
//             _values.push_back(QPointF(dt, data["厚度"]));
//             if (_values.size() > 1000)
//             {
//                 _values.pop_front();
//             }
        }

        class ValuePageImpl : public Impl<ValuePage>
        {
        public:
            void init();


        public:
            ValueSplineView* _spline;

//            ValueSplineView* _widthSpline;

            ToolProfilesView* _profile;

            ValueLabel* _value;

        /*    ValueLabel* _width;*/

            ValueLabel* _thicknessCp;

            ValueLabel* _thicknessCpk;

//             ValueLabel* _wCp;
// 
//             ValueLabel* _wCpk;

//             QLineEdit* _setPos;
//             QLineEdit* _curPos;
//             QPushButton* _move;

            QTimer _timer;
            QList<double> _thicknessList;
//            QList<double> _wList;

            double _valueMax;
            double _valueMin;

//             double _wMax;
//             double _wMin;

        public:
            ProductParams _params;

        public:
            void updateCPCPK(const double value, const double width);
            void setValue(const double dt, const double value, const double width);
            void updateTol(ValueLabel* label, int index, QString key);
            void updateTol(ValueSplineView* view, int index, QString key);
            void updateTol(double& upper, double& lower, int index, QString key);
        };

        void ValuePageImpl::init()
        {
            OI_Q(ValuePage);

            QVBoxLayout* mainLayout = new QVBoxLayout(q);

            _profile = new ToolProfilesView();

            _profile->setPageFlag(PMP_FixedMeasure);


//             QFormLayout* layout1 = new QFormLayout();

//             _setPos = new QLineEdit();
//             _curPos = new QLineEdit();
//             _move = new QPushButton(ValuePage::tr("开始定位"));
            _value = new ValueLabel();
            _value->setText(ValuePage::tr("厚度"));
            _value->setPrecise(2);
            _value->setUnit("mm");
            _value->setCheckEnable(true);
            //_value->setMinimumHeight(300);

            _thicknessCp = new ValueLabel(q);
            _thicknessCp->setText("CP");
            _thicknessCp->setPrecise(2);
            _thicknessCp->setUnit("");
            _thicknessCp->setCheckEnable(true);
            _thicknessCp->setEarlyLower(1.0);
            _thicknessCp->setLower(0.67);
            _thicknessCp->setUpper(MAX_LIMIT_VALUE);

            _thicknessCpk = new ValueLabel(q);
            _thicknessCpk->setText("CPK");
            _thicknessCpk->setPrecise(2);
            _thicknessCpk->setUnit("");
            _thicknessCpk->setCheckEnable(true);
            _thicknessCpk->setEarlyLower(1.0);
            _thicknessCpk->setLower(0.67);
            _thicknessCpk->setUpper(MAX_LIMIT_VALUE);

//             _width = new ValueLabel();
//             _width->setText(ValuePage::tr("总宽EL"));
//             _width->setPrecise(2);
//             _width->setUnit("mm");
//             _width->setCheckEnable(true);
//             //_width->setMinimumHeight(300);
// 
//             _wCp = new ValueLabel(q);
//             _wCp->setText("CP");
//             _wCp->setPrecise(2);
//             _wCp->setUnit("");
//             _wCp->setCheckEnable(true);
//             _wCp->setEarlyLower(1.0);
//             _wCp->setLower(0.67);
//             _wCp->setUpper(MAX_LIMIT_VALUE);
// 
//             _wCpk = new ValueLabel(q);
//             _wCpk->setText("CPK");
//             _wCpk->setPrecise(2);
//             _wCpk->setUnit("");
//             _wCpk->setCheckEnable(true);
//             _wCpk->setEarlyLower(1.0);
//             _wCpk->setLower(0.67);
//             _wCpk->setUpper(MAX_LIMIT_VALUE);

//             _setPos->setValidator(new QDoubleValidator());
//             _curPos->setReadOnly(true);
//             layout1->addRow(ValuePage::tr("定点位置"), _setPos);
//             layout1->addRow(ValuePage::tr("当前位置"), _curPos);

//            llayout->addWidget(_move);
            //llayout->addStretch();

            _spline = new ValueSplineView({ "厚度"});
//            _widthSpline = new ValueSplineView({ "总宽EL" });

            QGridLayout* blayout = new QGridLayout();
            blayout->addWidget(_value, 0, 0, 2, 1);
            blayout->addWidget(_thicknessCp, 0, 1, 1, 1);
            blayout->addWidget(_thicknessCpk, 1, 1, 1, 1);
            blayout->addWidget(_spline, 0, 2, 4, 1);

//             blayout->addWidget(_width, 4, 0, 2, 1);
//             blayout->addWidget(_wCp, 4, 1, 1, 1);
//             blayout->addWidget(_wCpk, 5, 1, 1, 1);
//             blayout->addWidget(_widthSpline, 4, 2, 4, 1);

            blayout->setColumnStretch(0, 0);
            blayout->setColumnStretch(1, 0);
            blayout->setColumnStretch(2, 6);
           

            mainLayout->addWidget(_profile, 1);
            mainLayout->addLayout(blayout, 1);

            _thicknessCp->hide();
            _thicknessCpk->hide();
        }

        void ValuePageImpl::updateCPCPK(const double value, const double width)
        {
            _thicknessList.push_back(value);

            if (_thicknessList.size() > 100)
            {
                _thicknessList.pop_front();
            }

            if (_thicknessCp->isVisible() && _thicknessCpk->isVisible())
            {
                if (_thicknessList.size() < 10)
                {
                    _thicknessCp->setValue(0.0);
                    _thicknessCpk->setValue(0.0);
                }
                else
                {
                    double cp, cpk;
                    PLScannerUtil::calCPCPK(_thicknessList, cp, cpk, _valueMax, _valueMin);
                    _thicknessCp->setValue(cp);
                    _thicknessCpk->setValue(cpk);
                }
            }

//             _wList.push_back(width);
// 
//             if (_wList.size() > 100)
//             {
//                 _wList.pop_front();
//             }
// 
//             if (_wCp->isVisible() && _wCpk->isVisible())
//             {
//                 if (_wList.size() < 10)
//                 {
//                     _wCp->setValue(0.0);
//                     _wCpk->setValue(0.0);
//                 }
//                 else
//                 {
//                     double cp, cpk;
//                     PLScannerUtil::calCPCPK(_wList, cp, cpk, _wMax, _wMin);
//                     _wCp->setValue(cp);
//                     _wCpk->setValue(cpk);
//                 }
//             }
        }

        void ValuePageImpl::setValue(const double dt, const double value, const double width)
        {
            _value->setValue(value);
//            _width->setValue(width);

            QMap<QString, double> vm;
            vm["厚度"] = value;

//             QMap<QString, double> wm;
//             wm["总宽EL"] = width;

            _spline->addData(dt, vm);
//            _widthSpline->addData(dt, wm);
        }

        void ValuePageImpl::updateTol(ValueLabel* label, int index, QString key)
        {
            int enable = 0;
            double warningTol = 0.0;
            double errorTol = 0.0;
            double stdValue = 0.0;

            if (_params.getMeasureEnable(index, key, enable) &&
                _params.getMeasureWarningTol(index, key, warningTol) &&
                _params.getMeasureErrorTol(index, key, errorTol) &&
                _params.getStdValue(index, key, stdValue))
            {
                label->setEnabled(true);
                if (enable & TC_WarningEnable)
                {
                    label->setEarlyUpper(stdValue + warningTol);
                    label->setEarlyLower(stdValue - warningTol);
                }

                if (enable & TC_ErrorEnable)
                {
                    label->setUpper(stdValue + errorTol);
                    label->setLower(stdValue - errorTol);
                }
            }
            else
            {
                label->setEnabled(false);
            }
        }

        void ValuePageImpl::updateTol(ValueSplineView* view, int index, QString key)
        {
            double errorTol = 0.0;
            double stdValue = 0.0;
            if (_params.getMeasureErrorTol(index, key, errorTol) &&
                _params.getStdValue(index, key, stdValue))
            {
                view->setLimit(stdValue + errorTol, stdValue - errorTol);
            }
        }

        void ValuePageImpl::updateTol(double& upper, double& lower, int index, QString key)
        {
            double errorTol = 0.0;
            double stdValue = 0.0;

            if (_params.getMeasureErrorTol(index, key, errorTol) &&
                _params.getStdValue(index, key, stdValue))
            {
                upper = stdValue + errorTol;
                lower = stdValue - errorTol;
            }
            else
            {
                upper = 0;
                lower = 0;
            }
        }

        ValuePage::ValuePage(QWidget * parent /*= nullptr*/)
            : PageAbstract(parent)
        {
            OI_I(ValuePage)->init();
        }
   

        void ValuePage::setParams(const PLScannerCore::ProductParams& params)
        {
            OI_F(ValuePage);

            if (d->_params == params)
            {
                return;
            }

            d->_params = params;
            d->_profile->setParams(params);
            d->_profile->zoomFit();

            d->updateTol(d->_value, TT_FixedPointMeasure, "y");
            d->updateTol(d->_spline, TT_FixedPointMeasure, "y");
            d->updateTol(d->_valueMax, d->_valueMin, TT_FixedPointMeasure, "y");

//             d->updateTol(d->_width, TT_TotolWidth, "x");
//             d->updateTol(d->_widthSpline, TT_TotolWidth, "x");
//             d->updateTol(d->_wMax, d->_wMin, TT_TotolWidth, "x");

            d->_thicknessList.clear();
        }

        int ValuePage::setResult(const PLScannerCore::WorkResult::Result& result)
        {
            return 0;
        }

        int ValuePage::setMsrResult(const std::vector<QPointF>& msrRes, bool insert)
        {
            return WorkResult::RC_Success;
        }

        int ValuePage::setValue(const double value, const double width)
        {
            OI_F(ValuePage);

            int resultCode = WorkResult::RC_Success;

            if (value <= 0.1)
            {
                return resultCode;
            }
            auto dt = QDateTime::currentDateTime().toMSecsSinceEpoch();
            d->setValue(dt, value, width);
            d->updateCPCPK(value, width);

            if (resultCode == WorkResult::RC_Success)
            {
                if (d->_value->status() == ValueLabel::LS_Error)
                {
                    resultCode = WorkResult::RC_Error;
                }
                else if (d->_value->status() == ValueLabel::LS_Warning)
                {
                    resultCode = WorkResult::RC_Warning;
                }
            }

            if (resultCode == WorkResult::RC_Success)
            {
                Motor::instance()->setResult(1);
            }
            else if (resultCode == WorkResult::RC_Warning)
            {
                Motor::instance()->setResult(0);
            }
            else
            {
                Motor::instance()->setResult(2);
            }

            return resultCode;
        }

        void ValuePage::setRun(bool flag)
        {
            OI_F(ValuePage);
            d->_spline->run(flag);
//            d->_widthSpline->run(flag);
        }

        void ValuePage::toCurrent()
        {
            OI_F(ValuePage);
            d->_spline->toCurrent();
//            d->_widthSpline->toCurrent();

        }

        void ValuePage::updatePermission()
        {
            OI_F(ValuePage);

            d->_thicknessCp->setVisible(UserManage::instance()->permission() & PT_ViewStatistics);
            d->_thicknessCpk->setVisible(UserManage::instance()->permission() & PT_ViewStatistics);

//             d->_wCp->setVisible(UserManage::instance()->permission() & PT_ViewStatistics);
//             d->_wCpk->setVisible(UserManage::instance()->permission() & PT_ViewStatistics);
        }

        void ValuePage::update()
        {
            OI_F(ValuePage);
            d->_spline->update();
//            d->_widthSpline->update();
        }

        void ValuePage::resizeEvent(QResizeEvent *event)
        {
            OI_F(ValuePage);
            d->_profile->zoomFit();

        }

        void ValuePage::showEvent(QShowEvent *event)
        {
            OI_F(ValuePage);
            d->_profile->zoomFit();
            toCurrent();
        }

    }
}